home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / sml_nj / 93src.lha / src / hppa / hppamc.sml < prev   
Encoding:
Text File  |  1993-01-27  |  19.4 KB  |  575 lines

  1. (* Copyright 1992 Scott Draves *)
  2.  
  3. structure HppaMCode =
  4. struct
  5.     local
  6.     open ByteArray
  7.     in
  8.     val code = ref (array(0, 0))
  9.  
  10.     fun getCodeString () =
  11.         let val s = extract (!code, 0, length (!code))
  12.         in  code := array(0, 0);
  13.             s
  14.         end
  15.  
  16.     end (* local *)
  17. end (* HppaMCode *)
  18.  
  19. structure HppaMCEmit : EMITTER =
  20. struct
  21.  
  22.     open HppaMCode HppaInstr
  23.  
  24.   (* Bit-wise operations *)
  25.     val << = Bits.lshift
  26.     val >> = Bits.rshift
  27.     val ++ = Bits.orb
  28.     val & = Bits.andb
  29.     infix << >> ++ &
  30.  
  31.     val loc = ref 0     (* the location counter *)
  32.  
  33.     fun emitByte n =
  34.     let val i = !loc
  35.     in  loc := i+1;
  36.         ByteArray.update (!code, i, n)
  37.     end
  38.  
  39.     fun emitWord n = (emitByte((n >> 8) & 255); emitByte(n & 255))
  40.  
  41.     fun emitLong n = (emitWord(n >> 16); emitWord(n & 65535))
  42.  
  43.     fun emitString s = let
  44.       fun copy i = (emitByte(ordof(s, i)); copy(i+1))
  45.       in
  46.         (copy 0) handle Ord => ()
  47.       end
  48.  
  49.     (* all hppa instructions consist of a 6 bit identifier, followed by
  50.        the 26 bit instruction specific body. *)
  51.     fun emit(id, body) =
  52.     let val b1 = (id << 2) ++ (body >> 24)
  53.         and b2 = (body >> 16) & 255
  54.         and b3 = (body >> 8) & 255
  55.         and b4 = body & 255
  56.         and i = !loc
  57.     in
  58.         ByteArray.update(!code, i  , b1);
  59.         ByteArray.update(!code, i+1, b2);
  60.         ByteArray.update(!code, i+2, b3);
  61.         ByteArray.update(!code, i+3, b4);
  62.         loc := i+4
  63.     end handle _ => ErrorMsg.impossible "HppaMCEmit.emit range"
  64.  
  65.     exception BadReal = IEEEReal.BadReal
  66.     fun emitReal s = emitString(IEEEReal.realconst s)
  67.  
  68.     fun emitAddr (info as INFO{addrOf, ...}) (lab, k) =
  69.     emitLong (k + addrOf(lab) - !loc)
  70.  
  71.     fun define _ _ = ()
  72.  
  73.     local
  74.     open System.Tags
  75.     in
  76.     fun mark () = emitLong (make_desc((!loc + 4) >> 2, tag_backptr))
  77.     end
  78.  
  79.     local
  80.     fun ms2u ms_none   = 0
  81.       | ms2u ms_modify = 0
  82.       | ms2u _         = 1
  83.  
  84.     fun ms2m ms_shift = 0
  85.       | ms2m ms_none  = 0
  86.       | ms2m _        = 1
  87.  
  88.     fun mab2a mab_before = 1
  89.       | mab2a _          = 0
  90.  
  91.     fun mab2m mab_none = 0
  92.       | mab2m _        = 1
  93.  
  94.     fun mbe2a mbe_begin        = 0
  95.       | mbe2a mbe_begin_modify = 0
  96.       | mbe2a _                = 1
  97.  
  98.     fun mbe2m mbe_begin = 0
  99.       | mbe2m mbe_end   = 0
  100.           | mbe2m _         = 1
  101.  
  102.         fun nullify2b n_nullify = 1
  103.       | nullify2b _         = 0
  104.  
  105.     fun arithcond2c cc_never                  = 0
  106.       | arithcond2c cc_equal                  = 1
  107.       | arithcond2c cc_less                   = 2
  108.       | arithcond2c cc_less_or_equal          = 3
  109.       | arithcond2c cc_less_unsigned          = 4
  110.       | arithcond2c cc_less_or_equal_unsigned = 5
  111.       | arithcond2c cc_signed_overflow        = 6
  112.       | arithcond2c cc_odd                    = 7
  113.  
  114.     fun arithcond22c (cc x)     = arithcond2c(x)
  115.       | arithcond22c (cc_not x) = arithcond2c(x)
  116.  
  117.     fun arithcond22f (cc x)     = 0
  118.       | arithcond22f _          = 1
  119.  
  120.     fun logicond2c lc_never                      = 0
  121.       | logicond2c lc_all_zero                   = 1
  122.       | logicond2c lc_leftmost_one               = 2
  123.       | logicond2c lc_leftmost_one_or_all_zero   = 3
  124.       | logicond2c lc_rightmost_one              = 7
  125.       | logicond2c lc_always                     = 0
  126.       | logicond2c lc_some_one                   = 1
  127.       | logicond2c lc_leftmost_zero              = 2
  128.       | logicond2c lc_leftmost_zero_and_some_one = 3
  129.       | logicond2c lc_rightmost_zero             = 7
  130.  
  131.     fun logicond2f lc_never                      = 0
  132.       | logicond2f lc_all_zero                   = 0
  133.       | logicond2f lc_leftmost_one               = 0
  134.       | logicond2f lc_leftmost_one_or_all_zero   = 0
  135.       | logicond2f lc_rightmost_one              = 0
  136.       | logicond2f _                             = 1
  137.  
  138.     fun unitcond2c uc_never               = 0
  139.       | unitcond2c uc_some_byte_zero      = 2
  140.       | unitcond2c uc_some_halfword_zero  = 3
  141.       | unitcond2c uc_some_digit_carry    = 4
  142.       | unitcond2c uc_some_byte_carry     = 6
  143.       | unitcond2c uc_some_halfword_carry = 7
  144.         
  145.     fun unitcond22c (uc x)     = unitcond2c(x)
  146.       | unitcond22c (uc_not x) = unitcond2c(x)
  147.  
  148.     fun unitcond22f (uc x)     = 0
  149.       | unitcond22f _          = 1
  150.  
  151.     fun shiftcond2b sc_never          = 0
  152.       | shiftcond2b sc_all_zero       = 1
  153.       | shiftcond2b sc_leftmost_one   = 2
  154.       | shiftcond2b sc_rightmost_one  = 3
  155.       | shiftcond2b sc_always         = 4
  156.       | shiftcond2b sc_some_one       = 5
  157.       | shiftcond2b sc_leftmost_zero  = 6
  158.       | shiftcond2b sc_rightmost_zero = 7
  159.         
  160.     fun fpf2b fpf_single = 0
  161.       | fpf2b fpf_double = 1
  162.       | fpf2b fpf_quad   = 3 (* no typo *)
  163.  
  164.     fun fpcond2b (fpc {less, greater, equal, unordered, trap}) =
  165.         let val n =     (if trap      then  1 else 0)
  166.         val n = n + (if unordered then  2 else 0)
  167.         val n = n + (if equal     then  4 else 0)
  168.         val n = n + (if less      then  8 else 0)
  169.         val n = n + (if greater   then 16 else 0)
  170.         in n
  171.         end
  172.  
  173.     fun fphalf FrLeftHalf  = 0
  174.       | fphalf FrRightHalf = 1
  175.  
  176.     (* should do bounds check here for added protection? XXX *)
  177.     fun bits5  n = n &      31
  178.     fun bits11 n = n &    2047
  179.     fun bits12 n = n &    4095
  180.     fun bits13 n = n &    8191
  181.     fun bits14 n = n &   16383
  182.     fun bits17 n = n &  131071
  183.     fun bits21 n = n & 2097151
  184.  
  185.     (* these put the sign bit last instead of first *)
  186.     fun bits5low  n = ((n &    0xf) << 1) ++ ((n &   0x10) >>  4)
  187.     fun bits11low n = ((n &  0x3ff) << 1) ++ ((n &  0x400) >> 10)
  188.     fun bits14low n = ((n & 0x1fff) << 1) ++ ((n & 0x2000) >> 13)
  189.  
  190.     fun frag3 n = ((n & 1) << 2) ++ ((n & 5) >> 1)
  191.  
  192.         fun frag21 n = (((n & 0x000003) << 12) ++
  193.             ((n & 0x00007c) << 14) ++
  194.             ((n & 0x000180) << 7) ++
  195.             ((n & 0x0ffe00) >> 8) ++
  196.             ((n & 0x100000) >> 20))
  197.  
  198.     fun frag17_0 n = (n & 0x10000) >> 16
  199.     fun frag17_1 n = (n & 0x0f800) >> 11
  200.     fun frag17_2 n = (((n & 0x3ff) << 1) ++
  201.               ((n & 0x400) >> 10))
  202.  
  203.     fun frag12_0 n = (n & 0x800) >> 11
  204.     fun frag12_1 n = (((n & 0x400) >> 10) ++
  205.               ((n & 0x3ff) << 1))
  206.  
  207.     fun emit_mem_offset(code, (REG base, im, REG t)) =
  208.         emit(code, (base << 21) ++ (t << 16) ++ bits14low(im))
  209.  
  210.     fun emit_mem_index(code, size, (REG r1, REG r2, ms, REG t)) =
  211.         emit(code,
  212.          (r1 << 21) ++ (r2 << 16) ++
  213.          (ms2u(ms) << 13) ++ (ms2m(ms) << 5) ++
  214.          t ++ (size << 6))
  215.  
  216.     fun emit_ld_short(code, size, (REG r1, im, mab, REG t)) =
  217.         emit(code,
  218.           (r1 << 21) ++ (bits5low(im) << 16) ++
  219.          (mab2a(mab) << 13) ++ (mab2m(mab) << 5) ++
  220.          t ++ (size << 6) ++ (1 << 12))
  221.  
  222.     fun emit_st_short(code, size, (REG r1, im, mab, REG t)) =
  223.         emit(code,
  224.           (r1 << 21) ++ (t << 16) ++
  225.          (mab2a(mab) << 13) ++ (mab2m(mab) << 5) ++
  226.          bits5low(im) ++ (size << 6) ++ (1 << 12))
  227.  
  228.     fun emit_st_bytes(code, size, (REG r1, im, mbe, REG t)) =
  229.         emit(code,
  230.          (r1 << 21) ++ (t << 16) ++
  231.          (mbe2a(mbe) << 13) ++ (mbe2m(mbe) << 5) ++
  232.          bits5low(im) ++ (size << 6) ++ (1 << 12))
  233.  
  234.     fun emit_branch(code, b, (im, n, REG t)) =
  235.         let val im = bits17(im)
  236.         in emit(code,
  237.             (t << 21) ++ (frag17_1(im) << 16) ++
  238.             (b << 13) ++ (frag17_2(im) << 2) ++
  239.             (nullify2b(n) << 1) ++ frag17_0(im))
  240.         end
  241.  
  242.     fun emit_branchs(code, (im, n, SREG s, t)) =
  243.         emit_branch(code, frag3(s), (im, n, t))
  244.  
  245.     fun emit_branch2(code, b, (REG x, n, REG t)) =
  246.         emit(code,
  247.          (t << 21) ++ (x << 16) ++
  248.          (b << 13) ++ (nullify2b(n) << 1))
  249.  
  250.     fun emit_branch3(code, (i, REG r, cond, im, n)) =
  251.         let val i = bits5low(i)
  252.         and im = bits12(im)
  253.         in emit(code,
  254.             (r << 21) ++ (i << 16) ++
  255.             (arithcond2c(cond) << 13) ++
  256.             (frag12_1(im) << 2) ++ (nullify2b(n) << 1) ++
  257.             frag12_0(im))
  258.         end
  259.  
  260.     fun emit_branch3r(code, (REG r1, REG r2, cond, im, n)) =
  261.         let val im = bits12(im)
  262.         in emit(code,
  263.             (r2 << 21) ++ (r1 << 16) ++
  264.             (arithcond2c(cond) << 13) ++
  265.             (frag12_1(im) << 2) ++ (nullify2b(n) << 1) ++
  266.             frag12_0(im))
  267.         end
  268.  
  269.     fun rrr(b, REG r1, REG r2, REG t) =
  270.         ((r2 << 21) ++ (r1 << 16) ++
  271.          (b << 5) ++ t)
  272.  
  273.     fun emit_add_rrr(code, b, (r1, r2, cond, t)) =
  274.         emit(code,
  275.          rrr(b, r1, r2, t) ++
  276.          (arithcond22c(cond) << 13) ++
  277.          (arithcond22f(cond) << 12))
  278.  
  279.     fun emit_log_rrr(code, b, (r1, r2, cond, t)) =
  280.         emit(code,
  281.          rrr(b, r1, r2, t) ++
  282.          (logicond2c(cond) << 13) ++
  283.          (logicond2f(cond) << 12))
  284.  
  285.     fun emit_unit_rrr(code, b, (r1, r2, cond, t)) =
  286.         emit(code,
  287.          rrr(b, r1, r2, t) ++
  288.          (unitcond22c(cond) << 13) ++
  289.          (unitcond22f(cond) << 12))
  290.  
  291.     fun emit_unit_rr(code, b, (r, t, cond)) =
  292.         emit(code,
  293.          rrr(b, REG 0, r, t) ++
  294.          (unitcond22c(cond) << 13) ++
  295.          (unitcond22f(cond) << 12))
  296.  
  297.     fun emit_add_irr(code, b, (im, REG r, cond, REG t)) =
  298.         emit(code,
  299.          (r << 21) ++ (t << 16) ++
  300.          (arithcond22c(cond) << 13) ++
  301.          (arithcond22f(cond) << 12) ++
  302.          (b << 11) ++ bits11low(im))
  303.  
  304.     fun emit_shift(code, b1, b2, r1, r2, cond, clen) =
  305.         emit(code,
  306.          (r1 << 21) ++ (r2 << 16) ++
  307.          (shiftcond2b(cond) << 13) ++
  308.          (b1 << 10) ++ (b2 << 5) ++ (32 - clen))
  309.  
  310.     fun emit_control(b, r1, r2, r3, s) =
  311.         emit(0, (r1 << 21) ++ (r2 << 16) ++
  312.          (frag3(s) << 13) ++ r3 ++ (b << 5))
  313.  
  314.     fun emit_fld_index(code, b, (REG r, REG x, ms, FREG t)) =
  315.         emit(code, (r << 21) ++ (x << 16) + t ++ (b << 9) ++
  316.          (ms2u(ms) << 13) ++ (ms2m(ms) << 5))
  317.  
  318.     fun emit_fld_short(code, b, (REG r, im, mab, FREG t)) =
  319.         emit(code, (r << 21) ++ (bits5low(im) << 16) ++ t ++ (b << 9) ++
  320.          (mab2a(mab) << 13) ++ (mab2m(mab) << 5) ++ (1 << 12))
  321.  
  322.  
  323.     fun emit_fldw_index(code, b, (REG r, REG x, ms, FREG t, half)) =
  324.         emit(code, (r << 21) ++ (x << 16) + t ++ (b << 9) ++
  325.          (ms2u(ms) << 13) ++ (ms2m(ms) << 5) ++ 
  326.          (fphalf half << 6))
  327.  
  328.     fun emit_fldw_short(code, b, (REG r, im, mab, FREG t, half)) =
  329.         emit(code, (r << 21) ++ (bits5low(im) << 16) ++ t ++ (b << 9) ++
  330.          (mab2a(mab) << 13) ++ (mab2m(mab) << 5) ++ (1 << 12) ++
  331.          (fphalf half << 6))
  332.  
  333.     fun emit_freg_freg(b, (FREG r, fpf, FREG t)) =
  334.         emit(0x0c, (r << 21) ++ t ++ (b << 13) ++ (fpf2b(fpf) << 11))
  335.  
  336.     fun emit_cnv(b, (FREG r, fpf1, FREG t, fpf2)) =
  337.         emit(0x0c, (r << 21) ++ t ++ (b << 15) ++ (1 << 9) ++
  338.          (fpf2b(fpf1) << 11) ++ (fpf2b(fpf2) << 13))
  339.  
  340.     fun emit_fop(b, (FREG r1, FREG r2, fpf, FREG t)) =
  341.         emit(0x0c, (r1 << 21) ++ (r2 << 16) ++ t ++
  342.          (b << 13) ++ (3 << 9) ++ (fpf2b(fpf) << 11))
  343.  
  344.     fun emit_fop2(code, (FREG r1, FREG r2, FREG r3, FREG r4, FREG r5)) =
  345.         emit(code, (r1 << 21) ++ (r2 << 16) ++ (r3 << 11) ++
  346.          (r4 << 6) ++ r5)
  347.  
  348.     in
  349.     (* all space codes are assumed to be 0
  350.        all cache hints are assumed to be 0 *)
  351.  
  352.     fun emitInstr info I =
  353.         case I of
  354.         (i_nop) => emitInstr(info)(i_addl(zero_reg, zero_reg, never, zero_reg))
  355.           |  (i_ldw(x))  => emit_mem_offset(0x12, x)
  356.           |  (i_ldh(x))  => emit_mem_offset(0x11, x)
  357.           |  (i_ldb(x))  => emit_mem_offset(0x10, x)
  358.           |  (i_stw(x))  => emit_mem_offset(0x1a, x)
  359.           |  (i_sth(x))  => emit_mem_offset(0x19, x)
  360.           |  (i_stb(x))  => emit_mem_offset(0x18, x)
  361.           |  (i_ldwm(x)) => emit_mem_offset(0x13, x)
  362.           |  (i_stwm(x)) => emit_mem_offset(0x1b, x)
  363.  
  364.           |  (i_ldwx(x))  => emit_mem_index(0x03, 0x2, x)
  365.           |  (i_ldhx(x))  => emit_mem_index(0x03, 0x1, x)
  366.           |  (i_ldbx(x))  => emit_mem_index(0x03, 0x0, x)
  367.           |  (i_ldwax(x)) => emit_mem_index(0x03, 0x6, x)
  368.           |  (i_ldcwx(x)) => emit_mem_index(0x03, 0x7, x)
  369.         
  370.           |  (i_ldws(x))  => emit_ld_short(0x03, 0x2, x)
  371.           |  (i_ldhs(x))  => emit_ld_short(0x03, 0x1, x)
  372.           |  (i_ldbs(x))  => emit_ld_short(0x03, 0x0, x)
  373.           |  (i_ldwas(x)) => emit_ld_short(0x03, 0x6, x)
  374.           |  (i_ldcws(x)) => emit_ld_short(0x03, 0x7, x)
  375.           |  (i_stws(x))  => emit_st_short(0x03, 0xa, x)
  376.           |  (i_sths(x))  => emit_st_short(0x03, 0x9, x)
  377.           |  (i_stbs(x))  => emit_st_short(0x03, 0x8, x)
  378.           |  (i_stwas(x)) => emit_st_short(0x03, 0xe, x)
  379.  
  380.           |  (i_stbys(x)) => emit_st_bytes(0x03, 0xc, x)
  381.         
  382.           |  (i_ldo(REG r1, im, REG t)) =>
  383.              emit(0x0d, (r1 << 21) ++ (t << 16) ++ bits14low(im))
  384.  
  385.           |  (i_ldil(im, REG t)) =>
  386.              emit(0x08, (t << 21) ++ frag21(bits21(im)))
  387.                     
  388.           |  (i_addil(im, REG t)) =>
  389.              emit(0x0a, (t << 21) ++ frag21(bits21(im)))
  390.  
  391.           |  (i_bl(x))     => emit_branch(0x3a, 0, x)
  392.           |  (i_gate(x))   => emit_branch(0x3a, 1, x)
  393.           |  (i_blr(x))    => emit_branch2(0x3a, 2, x)
  394.           |  (i_bv(x))     => emit_branch2(0x3a, 6, x)
  395.           |  (i_be(x))     => emit_branchs(0x38, x)
  396.           |  (i_ble(x))    => emit_branchs(0x39, x)
  397.           |  (i_movb(x))   => emit_branch3r(0x32, x)
  398.           |  (i_movib(x))  => emit_branch3(0x33, x)
  399.           |  (i_combt(x))  => emit_branch3r(0x20, x)
  400.           |  (i_combf(x))  => emit_branch3r(0x22, x)
  401.           |  (i_comibt(x)) => emit_branch3(0x21, x)
  402.           |  (i_comibf(x)) => emit_branch3(0x23, x)
  403.           |  (i_addbt(x))  => emit_branch3r(0x28, x)
  404.           |  (i_addbf(x))  => emit_branch3r(0x2a, x)
  405.           |  (i_addibt(x)) => emit_branch3(0x29, x)
  406.           |  (i_addibf(x)) => emit_branch3(0x2b, x)
  407.  
  408.           |  (i_bvb(REG r1, cond, im, n)) =>
  409.              let val im = bits12(im)
  410.              in emit(0x30, (r1 << 16) ++ (shiftcond2b(cond) << 13) ++
  411.                  (frag12_1(im) << 2) ++ (nullify2b(n) << 1) ++
  412.                  frag12_0(im))
  413.              end
  414.  
  415.           |  (i_bb(REG r1, p, cond, im, n)) =>
  416.              let val im = bits12(im)
  417.              and p = bits5(p)
  418.              in emit(0x31, (r1 << 16) ++ (shiftcond2b(cond) << 13) ++
  419.                  (frag12_1(im) << 2) ++ (nullify2b(n) << 1) ++
  420.                  frag12_0(im) ++ (p << 21))
  421.              end
  422.  
  423.           |  (i_add(x))     => emit_add_rrr(0x02, 0x30, x)
  424.           |  (i_addl(x))    => emit_add_rrr(0x02, 0x50, x)
  425.           |  (i_addo(x))    => emit_add_rrr(0x02, 0x70, x)
  426.           |  (i_addc(x))    => emit_add_rrr(0x02, 0x38, x)
  427.           |  (i_addco(x))   => emit_add_rrr(0x02, 0x78, x)
  428.           |  (i_sh1add(x))  => emit_add_rrr(0x02, 0x32, x)
  429.           |  (i_sh1addl(x)) => emit_add_rrr(0x02, 0x52, x)
  430.           |  (i_sh1addo(x)) => emit_add_rrr(0x02, 0x72, x)
  431.           |  (i_sh2add(x))  => emit_add_rrr(0x02, 0x34, x)
  432.           |  (i_sh2addl(x)) => emit_add_rrr(0x02, 0x54, x)
  433.           |  (i_sh2addo(x)) => emit_add_rrr(0x02, 0x74, x)
  434.           |  (i_sh3add(x))  => emit_add_rrr(0x02, 0x36, x)
  435.           |  (i_sh3addl(x)) => emit_add_rrr(0x02, 0x56, x)
  436.           |  (i_sh3addo(x)) => emit_add_rrr(0x02, 0x76, x)
  437.           |  (i_sub(x))     => emit_add_rrr(0x02, 0x20, x)
  438.           |  (i_subo(x))    => emit_add_rrr(0x02, 0x60, x)
  439.           |  (i_subb(x))    => emit_add_rrr(0x02, 0x28, x)
  440.           |  (i_subbo(x))   => emit_add_rrr(0x02, 0x68, x)
  441.           |  (i_subt(x))    => emit_add_rrr(0x02, 0x26, x)
  442.           |  (i_subto(x))   => emit_add_rrr(0x02, 0x66, x)
  443.           |  (i_ds(x))      => emit_add_rrr(0x02, 0x22, x)
  444.           |  (i_comclr(x))  => emit_add_rrr(0x02, 0x44, x)
  445.  
  446.           |  (i_or(x))      => emit_log_rrr(0x02, 0x12, x)
  447.           |  (i_xor(x))     => emit_log_rrr(0x02, 0x14, x)
  448.           |  (i_and(x))     => emit_log_rrr(0x02, 0x10, x)
  449.           |  (i_andcm(x))   => emit_log_rrr(0x02, 0x00, x)
  450.  
  451.           |  (i_uxor(x))    => emit_unit_rrr(0x02, 0x1c, x)
  452.           |  (i_uaddcm(x))  => emit_unit_rrr(0x02, 0x4c, x)
  453.           |  (i_uaddcmt(x)) => emit_unit_rrr(0x02, 0x4e, x)
  454.  
  455.           |  (i_dcor(x))    => emit_unit_rr(0x02, 0x5c, x)
  456.           |  (i_idcor(x))   => emit_unit_rr(0x02, 0x5e, x)
  457.  
  458.           |  (i_addi(x))    => emit_add_irr(0x2d, 0, x)
  459.           |  (i_addio(x))   => emit_add_irr(0x2d, 1, x)
  460.           |  (i_addit(x))   => emit_add_irr(0x2c, 0, x)
  461.           |  (i_addito(x))  => emit_add_irr(0x2c, 1, x)
  462.           |  (i_subi(x))    => emit_add_irr(0x25, 0, x)
  463.           |  (i_subio(x))   => emit_add_irr(0x25, 1, x)
  464.           |  (i_comiclr(x)) => emit_add_irr(0x24, 0, x)
  465.  
  466.           |  (i_vshd(REG r1, REG r2, cond, REG t)) =>
  467.              emit_shift(0x34, 0, 0, r2, r1, cond, 32-t)
  468.           |  (i_shd(REG r1, REG r2, cond, cp, REG t)) =>
  469.              emit_shift(0x34, 2, cp, r2, r1, cond, 32-t)
  470.  
  471.           |  (i_vextru(REG r, cond, len, REG t)) =>
  472.              emit_shift(0x34, 4, 0, r, t, cond, len)
  473.           |  (i_vextrs(REG r, cond, len, REG t)) =>
  474.              emit_shift(0x34, 5, 0, r, t, cond, len)
  475.           |  (i_extru(REG r, cond, start, len, REG t)) =>
  476.              emit_shift(0x34, 6, start, r, t, cond, len)
  477.           |  (i_extrs(REG r, cond, start, len, REG t)) =>
  478.              emit_shift(0x34, 7, start, r, t, cond, len)
  479.  
  480.           |  (i_vdep(REG r, cond, len, REG t)) =>
  481.              emit_shift(0x35, 1, 0, t, r, cond, len)
  482.           |  (i_dep(REG r, cond, start, len, REG t)) =>
  483.              emit_shift(0x35, 3, 31-start, t, r, cond, len)
  484.           |  (i_vdepi(im, cond, len, REG t)) =>
  485.              emit_shift(0x35, 5, 0, t, bits5low(im), cond, len)
  486.           |  (i_depi(im, cond, start, len, REG t)) =>
  487.              emit_shift(0x35, 7, 31-start, t, bits5low(im), cond, len)
  488.         
  489.           |  (i_zvdep(REG r, cond, len, REG t)) =>
  490.              emit_shift(0x35, 0, 0, t, r, cond, len)
  491.           |  (i_zdep(REG r, cond, start, len, REG t)) =>
  492.              emit_shift(0x35, 2, 31-start, t, r, cond, len)
  493.           |  (i_zvdepi(im, cond, len, REG t)) =>
  494.              emit_shift(0x35, 4, 0, t, bits5low(im), cond, len)
  495.           |  (i_zdepi(im, cond, start, len, REG t)) =>
  496.              emit_shift(0x35, 6, 31-start, t, bits5low(im), cond, len)
  497.  
  498.           | (i_break(im1, im2)) => emit(0, bits5(im1) ++ (bits13(im2) << 13))
  499.           | (i_rfi)  => emit_control(0x60, 0, 0, 0, 0)
  500.           | (i_rfir) => emit_control(0x65, 0, 0, 0, 0)
  501.           | (i_ssm(im, REG r)) => emit_control(0x6b, 0, bits5(im), r, 0)
  502.           | (i_rsm(im, REG r)) => emit_control(0x73, 0, bits5(im), r, 0)
  503.           | (i_mtsm(REG r)) => emit_control(0xc3, 0, r, 0, 0)
  504.           | (i_mtctl(REG r, CREG c)) => emit_control(0xc2, c, r, 0, 0)
  505.           | (i_mfctl(CREG c, REG r)) => emit_control(0x45, c, 0, r, 0)
  506.           | (i_ldsid(REG r, REG t)) => emit_control(0x85, r, 0, t, 0)
  507.           | (i_mtsp(REG r, SREG s)) => emit_control(0xc1, 0, r, 0, s)
  508.           | (i_mfsp(SREG s, REG r)) => emit_control(0x25, 0, 0, r, s)
  509.           | (i_sync) => emit_control(0x20, 0, 0, 0, 0)
  510.  
  511.           | (i_fldwx(x)) => emit_fldw_index(0x09, 0, x)
  512.           | (i_fstwx(x)) => emit_fldw_index(0x09, 1, x)
  513.           | (i_fldws(x)) => emit_fldw_short(0x09, 0, x)
  514.           | (i_fstws(x)) => emit_fldw_short(0x09, 1, x)
  515.  
  516.           | (i_flddx(x)) => emit_fld_index(0x0b, 0, x)
  517.           | (i_fstdx(x)) => emit_fld_index(0x0b, 1, x)
  518.           | (i_fldds(x)) => emit_fld_short(0x0b, 0, x)
  519.           | (i_fstds(x)) => emit_fld_short(0x0b, 1, x)
  520.  
  521.           | (i_fcpy(x))  => emit_freg_freg(2, x)
  522.           | (i_fabs(x))  => emit_freg_freg(3, x)
  523.           | (i_fsqrt(x)) => emit_freg_freg(4, x)
  524.           | (i_frnd(x))  => emit_freg_freg(5, x)
  525.         
  526.           | (i_fcnvff(x))  => emit_cnv(0, x)
  527.           | (i_fcnvxf(x))  => emit_cnv(1, x)
  528.           | (i_fcnvfx(x))  => emit_cnv(2, x)
  529.           | (i_fcnvfxt(x)) => emit_cnv(3, x)
  530.  
  531.           | (i_fcmp(FREG r1, FREG r2, fpf, cond)) =>
  532.             emit(0x0c, (r1 << 21) ++ (r2 << 16) ++ fpcond2b(cond) ++
  533.              (fpf2b(fpf) << 11) ++ (2 << 9))
  534.           | (i_ftest) =>
  535.             emit(0x0c, (1 << 13) ++ (2 << 9) ++ (1 << 5))
  536.  
  537.           | (i_fadd(x)) => emit_fop(0, x)
  538.           | (i_fsub(x)) => emit_fop(1, x)
  539.           | (i_fmpy(x)) => emit_fop(2, x)
  540.           | (i_fdiv(x)) => emit_fop(3, x)
  541.  
  542.           | (i_mpyadd(x)) => emit_fop2(0x06, x)
  543.           | (i_mpysub(x)) => emit_fop2(0x26, x)
  544.  
  545.           | i_sdi_ldo(r1, le, r2) =>
  546.             emitInstr info (i_ldo(r1, eval_label_expr(info, loc)(le), r2))
  547.           | i_sdi_addil(le, r) =>
  548.             emitInstr info (i_addil(eval_label_expr(info, loc)(le), r))
  549.           | i_sdi_ldil(le, r) =>
  550.             emitInstr info (i_ldil(eval_label_expr(info, loc)(le), r))
  551.           | i_sdi_ldw(r1, le, r2) =>
  552.             emitInstr info (i_ldw(r1, eval_label_expr(info, loc)(le), r2))
  553.           | i_sdi_comb(r1, r2, cc c, le, n) =>
  554.             emitInstr info (i_combt(r1, r2, c, eval_label_expr(info, loc)(le), n))
  555.           | i_sdi_comb(r1, r2, cc_not c, le, n) =>
  556.             emitInstr info (i_combf(r1, r2, c, eval_label_expr(info, loc)(le), n))
  557.           | i_sdi_bl(le, n, r) =>
  558.             emitInstr info (i_bl(eval_label_expr(info, loc)(le), n, r))
  559.           | i_sdi_bb(r, im, c, le, n) =>
  560.             emitInstr info (i_bb(r, im, c, eval_label_expr(info, loc)(le), n))
  561.           | i_nullified(i) =>
  562.             emitInstr info i
  563.  
  564.           |  i => ErrorMsg.impossible ("[HppaMCEmit.emitInstr "
  565.                        ^ HppaAsHelp.instr2string(info)(i) ^ "]")
  566.  
  567. end (* local *)
  568.  
  569.     fun comment _ = ()
  570.  
  571.     fun init n = (code := ByteArray.array(n, 0);
  572.           loc := 0)
  573.  
  574. end (* structure HppaMCEmit *)
  575.